package com.edu.tool.service.impl.login;



import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.edu.common.util.SimpleStringUtil;
import com.edu.tool.bean.linkbeans.user.SysEmpResponsiblity;
import com.edu.tool.bean.user.*;
import com.edu.tool.constant.MsgConstant;
import com.edu.tool.controller.signup.SysSignUpController;
import com.edu.tool.exception.BaseException;
import com.edu.tool.mapper.conf.SysTenantDictConfMapper;
import com.edu.tool.mapper.links.user.SysEmpResponsiblityMapper;
import com.edu.tool.mapper.user.*;

import com.edu.tool.service.sms.SysSmsService;
import com.edu.tool.service.user.SysCaptchaService;
import com.edu.tool.service.user.SysLoginTokenService;
import com.edu.tool.service.user.SysTenantService;
import com.edu.tool.util.IpUtil;
import com.edu.tool.util.MsgUtil;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

@Service
public class SysTenantServiceImpl implements SysTenantService {
    @Autowired
    private SysTenantMapMapper tenantMapMapper;

    @Autowired
    private SysTenantMapper tenantMapper;

    @Autowired
    private SysAuthTokenMapper authTokenMapper;

    @Autowired
    private SysTenantTrialMapper tenantTrialMapper;

    @Autowired
    private SysTenantRegisterMapper tenantRegisterMapper;

    @Autowired
    private SysTenantDictConfMapper tenantDictConfMapper;

    @Autowired
    private SysEmployeeMapper employeeMapper;

    @Autowired
    private SysReponsibilityMapper reponsibilityMapper;

    @Autowired
    private SysEmpResponsiblityMapper empResponsiblityMapper;

    @Autowired
    private SysCaptchaService captchaService;

    @Autowired
    private SysSmsService smsService;

    @Autowired
    private SysLoginTokenService loginTokenService;

    Logger logger = LoggerFactory.getLogger(SysTenantServiceImpl.class);

    public Map getAccountInfo(Integer tenantId){
        return new HashMap();
    }

    @Override
    public Integer getConfigTenantId(Integer tenantId) {
        QueryWrapper<SysTenantMap> queryMapper = new QueryWrapper<SysTenantMap>();
        queryMapper.lambda()
                .eq(SysTenantMap::getcTenantId,tenantId);

        SysTenantMap tenantMap  = tenantMapMapper.selectOne(queryMapper);
        if(tenantMap!=null&&tenantMap.getmTenantId()!=null)
            return tenantMap.getmTenantId();
        else
            return tenantId;
    }

    @Override
    @Transactional
    public Map createTrialUser(String ipAddress,
                        String authToken,
                        String phoneCode,
                        String name,
                        String mail,
                        String shortName,
                        String industry,
                        String channel)
    {

        Map result = new HashMap();

//        QueryWrapper<SysAuthToken> queryMapper = new QueryWrapper<SysAuthToken>();
//        queryMapper.lambda().eq(SysAuthToken::getAuthToken,authToken);
//        SysAuthToken sysAuthToken  = authTokenMapper.selectOne(queryMapper);
//
//        if(sysAuthToken == null){
//            result = MsgUtil.retMsgMap(MsgConstant.INVALID_AUTHCODE,"验证码错误");
//            throw new BaseException((String)result.get("error_code"),(String)result.get("error_message") );
//        }

        Map verifyRet = smsService.isValidAuthCode(authToken, phoneCode);
        Integer retcode = (Integer)verifyRet.get("error_code");
        if(retcode == 0 ){
            String phone =(String) ( (HashMap)verifyRet.get("authresult")).get("phone") ;
            QueryWrapper<SysTenantTrial> tenantTrialQR = new QueryWrapper<>();
            tenantTrialQR.lambda().eq(SysTenantTrial::getPhone, phone);
            SysTenantTrial tenantTrial = tenantTrialMapper.selectOne(tenantTrialQR);

            if(tenantTrial != null){
                result =  MsgUtil.retMsgMap(MsgConstant.REGISTERED_PHONE_CODE);
                throw new BaseException((String)result.get("error_code"),(String)result.get("error_message") );

            }
            SysTenantTrial newTrial = new SysTenantTrial();
            Date now = new Date();
            newTrial.setName(name);
            newTrial.setPhone(phone);
            newTrial.setMail(mail);
            newTrial.setShortName(shortName);
            newTrial.setIndustry(industry);
            newTrial.setIpAddress(ipAddress);
            newTrial.setChannel(channel);
            newTrial.setCreate_time(now);
            newTrial.setUpdate_time(now);
            newTrial.setStatus(1);//1 试用中 2 已过期
            tenantTrialMapper.insert(newTrial);

            //在demo租户中创建当前员工，并赋予admin权限，发送通知短信，密码随机六位数字
            QueryWrapper<SysTenantDictConf> sysTenantDictConfQR = new QueryWrapper<>();
            sysTenantDictConfQR.lambda().eq(SysTenantDictConf::getDictId,"trial_tenant_id");
            SysTenantDictConf sysTenantDictConf = tenantDictConfMapper.selectOne(sysTenantDictConfQR);

            Integer trialTenantId = Integer.valueOf(sysTenantDictConf.getDictValue());

            QueryWrapper<SysEmployee> sysEmployeeQR = new QueryWrapper<>();

            sysEmployeeQR.lambda().eq(SysEmployee::getTenantId,trialTenantId)
                    .eq(SysEmployee::getPhone,phone);
            SysEmployee sysEmployee = employeeMapper.selectOne(sysEmployeeQR);

            if(sysEmployee != null){
                result = MsgUtil.retMsgMap(MsgConstant.REGISTERED_PHONE_CODE);
                throw new BaseException((String)result.get("error_code"),(String)result.get("error_message") );
            }
            SysEmployee newEmp = new SysEmployee();
            newEmp.setTenantId(trialTenantId);
            newEmp.setPhone(phone);
            newEmp.setName(name);
            newEmp.setLoginName(phone);
            String randomPwd = String.valueOf((int)((Math.random() * 9 + 1) * 100000));
            newEmp.setLoginPwd(SimpleStringUtil.getMD5Str(randomPwd));
            employeeMapper.insert(newEmp);

            //获取id为1的Res(demo租户此权限为admin权限)

            QueryWrapper<SysResp> sysResponsibilityQR = new QueryWrapper<>();
            sysResponsibilityQR.lambda().eq(SysResp::getTenantId,trialTenantId)
                    .eq(SysResp::getId,1252);

            SysResp res = reponsibilityMapper.selectOne(sysResponsibilityQR);
            SysEmpResponsiblity empResLink = new SysEmpResponsiblity();
            empResLink.setTenantId(trialTenantId);
            empResLink.setEmpId(newEmp.getId());
            empResLink.setResId(res.getUuid());
            empResponsiblityMapper.insert(empResLink);


            //返回试用员工信息，前端直接跳转登录；同时发送短信
            SysLoginToken loginToken;
            if(channel.equals("wechat")){
                //微信端申请试用
                loginToken = loginTokenService.createTokenPortal(trialTenantId,
                        "2",
                        newEmp.getId(),
                        null,
                        null,
                        ipAddress,
                        "wechat-trial");
            } else {
                //PC端申请试用
                loginToken = loginTokenService.createTokenPortal(trialTenantId,
                        "2",
                        newEmp.getId(),
                        null,
                        null,
                        ipAddress,
                        "pc-trial");
            }
            //发送短信
            Map<String, String> placeholderMap = new HashMap<String, String>();
            placeholderMap.put("loginPwd", ""+randomPwd);
            placeholderMap.put("phone", ""+phone);
            //Map smsResult = smsService.sendNotifySms(153, "MSG_TRIAL_SUCCESS", phone, placeholderMap);
            //if(smsResult.get("retcode").equals("fail"))
            //    logger.error("charge, sms after charge is not send successfully");
            result.put("token", loginToken.getToken());
            result.put("empId", newEmp.getId());
            result.put("randomPwd",randomPwd);
            return MsgUtil.retMap("trialuser",result);
        }
        else
        {
            result = MsgUtil.retMsgMap(MsgConstant.FAILED_RET,"验证码错误。");
            throw new BaseException((String)result.get("error_code"),(String)result.get("error_message") );
        }
    }

    @Override
    @Transactional
    public Map createRegisterUser(
                            String ipAddress ,
                            String authToken,
                            String phoneCode,
                            String pwd,
                            String companyName,
                            Integer template,
                            String domain,
                            String employeeName,
                            String openId,
                            Integer tenantType){
        Map result = new HashMap();

        if(tenantType==null)
        {
            //默认丙类
            tenantType = 3;
        }
        if(tenantType!=1 && tenantType!=2 && tenantType!=3)
        {
            result = MsgUtil.retMsgMap(MsgConstant.FAILED_RET,"tenantType异常，只能为1,2,3。");
            return result;
        }
        //make sure authToken is valid
        Map verifyRet = smsService.isValidAuthCode(authToken, phoneCode);
        Integer retcode = (Integer)verifyRet.get("error_code");
        if(retcode == 0 ) {

            //make sure domain is valid
            if(StringUtils.isEmpty(domain))
            {
                result = MsgUtil.retMsgMap(MsgConstant.FAILED_RET,"域名domain不能为空");
                return result;
            }
            Pattern pattern = Pattern.compile("[a-z0-9][a-z0-9_]{2,14}");
            Matcher matcher = pattern.matcher(domain);
            boolean b= matcher.matches();
            if(!b)
            {

                result = MsgUtil.retMsgMap(MsgConstant.FAILED_RET,"域名domain非法，允许输入3-15位字母、数字、下划线组合");
                return result;
            }
            if("product".equals(domain))
            {
                result = MsgUtil.retMsgMap(MsgConstant.FAILED_RET,"域名domain不能为product");
                return result;

            }
            if("younao".equals(domain))
            {
                result = MsgUtil.retMsgMap(MsgConstant.FAILED_RET,"域名domain不能为eis");
                return result;
            }
            QueryWrapper<SysTenantRegister> domainQR = new QueryWrapper<>();
            domainQR.lambda().eq(SysTenantRegister::getDomain,domain);
            List<SysTenantRegister> tenantRegisterList = tenantRegisterMapper.selectList(domainQR);


            if(tenantRegisterList!=null
                    && tenantRegisterList.size()>0)
            {
                result = MsgUtil.retMsgMap(MsgConstant.FAILED_RET,"domain已被使用了");
                return result;
            }
            QueryWrapper<SysTenant> tenantQR = new QueryWrapper<>();
            tenantQR.lambda().eq(SysTenant::getDomain,domain);
            List<SysTenant> tenantList= tenantMapper.selectList(tenantQR);
            if(tenantList!=null && tenantList.size() > 0)
            {
                result = MsgUtil.retMsgMap(MsgConstant.FAILED_RET,"domain已被使用了");
                return result;
            }

            //1.创建租户的注册信息
            String md5pwd = SimpleStringUtil.getMD5Str(pwd);
            SysTenantRegister tenantRegister = new SysTenantRegister();
            tenantRegister.setCompanyName(companyName);
            tenantRegister.setDomain(domain);
            tenantRegister.setPhone(phoneCode);
            tenantRegister.setTenantType(tenantType);
            Date now  = new Date();
            tenantRegister.setCreate_time(now);
            tenantRegister.setUpdate_time(now);
            tenantRegister.setCreate_by("system");
            tenantRegister.setUpdate_by("system");
            tenantRegister.setPwd(md5pwd);
            tenantRegister.setEmployeeName(employeeName);
            tenantRegister.setStatus("0");
            tenantRegisterMapper.insert(tenantRegister);


            //2. 创建新租户
            Integer newTenantId = 0;
            SysTenant tenant = new SysTenant();

            tenant.setTenantId(null);
            tenant.setCompanyInfo(companyName);
            tenant.setDomain(domain);
            tenant.setSmsRemain(0);
            tenant.setTenantType(tenantType);
            int count = tenantMapper.insert(tenant);
            if (count > 0) {
                // 更新租户ID
                newTenantId = tenant.getId();
                tenant.setTenantId(tenant.getId());
                tenantMapper.updateById(tenant);
            }

            //2. 创建租户的首个职员
            SysEmployee newEmp = new SysEmployee();
            newEmp.setTenantId(newTenantId);
            newEmp.setPhone(phoneCode);
            if (!StringUtils.isEmpty(employeeName)) {
                newEmp.setName(employeeName);
            } else {
                newEmp.setName("");
            }

            newEmp.setLoginName(phoneCode);
            newEmp.setOwner(1);
            newEmp.setPosition(null);
            newEmp.setOrganization(1);

            newEmp.setJobTitle("管理员");

            if (!StringUtils.isEmpty(md5pwd)) {
                newEmp.setLoginPwd(md5pwd);
            } else {
                newEmp.setLoginPwd("");
            }

            newEmp.setEmail(null);
            newEmp.setResponsibilityId(null);
            newEmp.setRoleType("admin");
            employeeMapper.insert(newEmp);


            //2.启用租户
            tenantRegister.setActiveTime(now);
            tenantRegister.setTenantId(newTenantId);
            tenantRegister.setStatus("1");
            tenantRegisterMapper.updateById(tenantRegister);

        }
        else
        {
            result = MsgUtil.retMsgMap(MsgConstant.FAILED_RET,"验证码错误。");
            throw new BaseException((String)result.get("error_code"),(String)result.get("error_message") );
        }
        return result;
    }
}